using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Text.RegularExpressions;

////////////////////////////////////
////Source: http://www.cyberbrutus.com/silverlight-numeric-textbox/
///////////////////////////////////////
namespace FU.Capstones.IMS.Web.Common.CustomControls
{
    ///

    /// Custom TextBox for handling numbers/decimals
    ///
    public class NumericTextBox : TextBox
    {
        #region Properties

        ///
        /// Number of decimal places
        ///
        public int DecimalPlaces { get; set; }

        ///
        /// Returns true if the control allows decimals
        ///
        public bool AllowDecimal
        {
            get { return (bool) GetValue(AllowDecimalProperty); }
            set
            {
                SetValue(AllowDecimalProperty, value);
            }
        }

        public static readonly DependencyProperty AllowDecimalProperty = DependencyProperty.Register("AllowDecimal", typeof (bool),
                                                                                     typeof (NumericTextBox),
                                                                                     new PropertyMetadata(false));

        #endregion

        #region Methods

        ///

        /// Returns true if there is a decimal
        ///
        ///
        private bool HasDecimal()
        {
            return Text.Contains(".");
        }

        ///

        /// Processes the numbers special if decimals are used
        ///
        ///
        private bool Handled()
        {
            bool handled = false;

            if (AllowDecimal && HasDecimal())
            {
                int indexOfDecimal = Text.IndexOf(".");

                if (SelectionStart > indexOfDecimal)
                    handled = (Text.Length - Text.IndexOf(".")) == (DecimalPlaces + 1);
            }

            return handled;

        }

        #endregion

        #region Events

        ///
        /// Handle the keydown event
        ///
        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Left:
                case Key.Right:
                case Key.Back:
                case Key.Shift:
                case Key.Home:
                case Key.End:
                case Key.Escape:
                case Key.Tab:
                    e.Handled = false;
                    break;
                case Key.D0:
                case Key.D1:
                case Key.D2:
                case Key.D3:
                case Key.D4:
                case Key.D5:
                case Key.D6:
                case Key.D7:
                case Key.D8:
                case Key.D9:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                    e.Handled = Handled();
                    break;
                case Key.Decimal:
                    {
                        e.Handled = !AllowDecimal || HasDecimal();
                        break;
                    }
                case Key.Unknown:
                    {
                        if (e.PlatformKeyCode == 190) // period
                        {
                            e.Handled = !AllowDecimal || HasDecimal();
                        }
                        break;
                    }
                default:
                    e.Handled = true;
                    break;
            }

            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Left:
                case Key.Right:
                case Key.Back:
                case Key.Shift:
                case Key.Home:
                case Key.End:
                case Key.Escape:
                case Key.Tab:
                    e.Handled = false;
                    break;
                default:
                    const string pattern = "[^0-9.]";
                    Text = Regex.Replace(Text, pattern, "");
                    Select(Text.Length, 0);
                    break;

            }
            base.OnKeyUp(e);
        }

        #endregion
    }
}
